﻿using System;
using System.Text;

namespace IniFileManager
{
	/// <summary>
	/// Class which represents section of ini file.
	/// </summary>
	sealed public class IniSection : IComparable<string>, IComparable<IniSection>, IComparable, IIniFileToken
	{
		/// <summary>
		/// Empty constant representing empty section. ( Section with empty name. )
		/// </summary>
		public static readonly IniSection EmptySection = new IniSection( "" );
		private string name;
		private UniqueList<IniProperty> properties;

		/// <summary>
		/// Constructor of IniSection.
		/// </summary>
		/// <param name="name">Name of the section.</param>
		public IniSection( string name )
		{
			this.name = name;
			this.properties = new UniqueList<IniProperty>();
		}

		/// <summary>
		/// Gets section's properties.
		/// </summary>
		public UniqueList<IniProperty> Properties
		{
			get
			{
				return this.properties;
			}
		}

		/// <summary>
		/// Gets section name.
		/// </summary>
		public string Name
		{
			get
			{
				return this.name;
			}
		}

		/// <summary>
		/// Method which add property to section.
		/// </summary>
		/// <param name="newProperty">New property.</param>
		public void AddProperty( IniProperty newProperty )
		{
			try
			{
				this.properties.Add( newProperty );
			}
			catch( ArgumentException )
			{
				throw new FormatException( "\"" + newProperty.Name + "\" property already exists." );
			}
		}

		/// <summary>
		/// Method which removes property from section.
		/// </summary>
		/// <param name="propertyName">Name of item which will be deleted.</param>
		public void RemoveProperty( string propertyName )
		{
			this.properties.Remove( this.properties[propertyName] );
		}

		/// <summary>
		/// Method which removes property from section.
		/// </summary>
		/// <param name="deletedProperty">Item which will be deleted.</param>
		public void RemoveProperty( IniProperty deletedProperty )
		{
			this.properties.Remove( deletedProperty );
		}

		#region Object Members

		/// <summary>
		/// Method which compares 2 section.
		/// </summary>
		/// <param name="obj">Compared obj.</param>
		/// <returns>Return true if properties are equal. Return false otherwise.</returns>
		public override bool Equals( object obj )
		{
			if( obj.GetType() != typeof( IniProperty ) )
			{
				return false;
			}

			return this.name.Equals( ( (IniProperty)obj ).Name );
		}

		/// <summary>
		/// Returns hash code of section.
		/// </summary>
		/// <returns>Hash code.</returns>
		public override int GetHashCode()
		{
			return this.name.GetHashCode();
		}

		/// <summary>
		/// Method transforming section to string. It return only section name.
		/// </summary>
		/// <returns>Section name.</returns>
		public override string ToString()
		{
			return this.name;
		}

		#endregion


		#region IComparable<IniSection> Members

		int IComparable<IniSection>.CompareTo( IniSection other )
		{
			throw new NotImplementedException();
		}

		#endregion

		#region IComparable<string> Members

		int IComparable<string>.CompareTo( string other )
		{
			if( this.name == other )
			{
				return 0;
			}
			else
			{
				return -1;
			}
		}

		#endregion

		#region IComparable Members

		int IComparable.CompareTo( object obj )
		{
			throw new NotImplementedException();
		}

		#endregion

		#region IIniFileToken Members

		string IIniFileToken.WriteSelf()
		{
			StringBuilder result = new StringBuilder();
			result.Append( TextConstants.sectionLeftBracket );
			result.Append( this.name );
			result.Append( TextConstants.sectionRightBracket );

			return result.ToString();
		}

		#endregion
	}
}
